Tips und Tricks

Rolf's Mathematica-Ecke

Im Auftrag für Mathemas Ordinate werde ich hier eine Tips & Tricks Ecke pflegen.

ANFRAGEN, KOMMENTARE, ERGÄNZUNGEN ETC. JEDERZEIT WILLKOMMEN.

Zunächst einmal sammle ich kleine wiederverwendbare Programme die ich selber bei verschiedenen Projekten gebraucht habe.

Weiterhin finden sich weiter ausgebaute Beispiele z.B. für J/Link.  Diese sind mit (TT), "Tips & Tricks", gekennzeichnet.
Manchmal findet man ein kleines erklärendes Beispiel das die Dokumentation von Standard Mathematica Functionen verbessert. Diese Abschnitte sind mit (Doku) markiert. Neuere Funktionen oder Symbole sind hier zum Teil auch beschrieben, gekennzeichnet durch (4.2).
Manchmal geht es auch nicht um eine Funktion sonder um eine Methode um etwas zu erreichen, z.B. deutsche Anführungsstriche.

In[2]:=

Date[]

Out[2]=

{2003, 3, 10, 12, 40, 27}

Im Mathematica Kernel gibt es von Version zu Version Änderungen. Z.B. ist in Version 4.2 ZTransform Teil des Kernels.

In[3]:=

? ZTransform

ZTransform[expr, n, z] gives the Z transform of expr. <a title= More... " hspace="55" width="418" height="15" align="absmiddle" />

In[57]:=

Off[General :: spel1] CasesH[expr_, {f___}, opts___Rule] := CasesH @@ Prepend[{f, opts}, expr] ; CasesH[expr_, f_, opts___Rule] := Union[Cases[{expr}, HoldPattern[f[___]], Infinity, opts]] ; <br /> CasesH[expr_, f___, g_] := Union[Cases[{expr}, Alternatives @@ (#[___] & /@ {f, g}), Infinity]] /; Head[g] =!= Rule ; <br /> CasesH[expr_, f__, Heads -> True] := Union[Cases[{expr}, Alternatives @@ (#[___] & /@ {f, g}), Infinity, Heads -> True]] ;  CasesH[expr_, f__, Heads -> False] := Union[Cases[{expr}, Alternatives @@ (#[___] & /@ {f, g}), Infinity, Heads -> False]] ;

In[63]:=

CasesH[ f[x] + f[a, b] - f, f]

Out[63]=

{f[x], f[a, b]}

Chomp[string] eliminiert alle Leerzeichen, Tabulatorzeichen und Zeilenumbrüche am Anfang und am Ende eines Strings.

In[10]:=

SetAttributes[Chomp, Listable] ; Chomp[""] = Chomp[" "] = "" ; Chomp[s_] := Chomp[s] = StringJoin @@ (Flatten[Replace[Split[Characters[s]], {{{(" " | "\t" | "\n" | "\r") ..}, b___, {(" " | "\n" | "\t" | "\r") ..}} :> {b}, {{(" " | "\n" | "\t" | "\r") ..}, r___} :> {r}, {a___, {(" " | "\n" | "\t" | "\r") ..}} :> {a}}]]) ; Null

General :: spell1 :  Possible spelling error: new symbol name \" Chomp \" is similar to existing symbol \" Chop \".

In[14]:=

Chomp["  test "] // InputForm

Out[14]//InputForm=

test

Seit Mathematica 4.2 gibt es eine neue boolsche Funtkion eingeführt, die testet ob ein Ausdruck Mitglied in einer bestimmten Zahlenmenge ist.

In[15]:=

NotElement[2^Sqrt[2], Algebraics]

Out[15]=

True

In[16]:=

123456789012345678901 ∉ Primes

Out[16]=

True

In[17]:=

2003 ∉ Primes

Out[17]=

False

Bei Funktionen mit mehreren Optionen ist manchmal der Standardbefehl Options etwas unübersichtlich. OptionSettings gibt eine geordnete tabellarische Übersicht.

In[1]:=

OptionSettings[symb_, style_:"Output"] :=
   StyleForm[
   (* Grid ist ein undokumentierter GridBox-ähnlicher Befehl *)
   Grid[
        (Replace[#1,
        (* wir wollen bei den Optionswerten sehen ob es ein String ist oder nicht, aber nicht das -> selber als String *)
        {(a_ -> b_) -> {a, StyleForm["->", ShowStringCharacters -> False], b},
         (a_ :> b_) -> {a, StyleForm[":>", ShowStringCharacters -> False], HoldForm[b]}}] & ) /@
         Sort[Options[symb], OrderedQ[{#1[[1]], #2[[1]]}] & ],
    RowLines -> True, GridFrame -> True, ColumnAlignments -> Left,
    ColumnSpacings -> 3], style, ShowStringCharacters -> True] /; ValueQ[$FrontEnd] && Options[symb] =!= {};

In[19]:=

OptionSettings[ButtonBox]

Out[19]//StyleForm=

Active -> False
Background -> Automatic
ButtonData :> Automatic
ButtonEvaluator -> None
ButtonExpandable -> True
ButtonFrame -> Palette
ButtonFunction :> FrontEndExecute[{FrontEnd`NotebookApply[FrontEnd`InputNotebook[], #1, Placeholder]}] &
ButtonMargins -> 3.`
ButtonMinHeight -> 1.`
ButtonNote -> None
ButtonSource -> Automatic
ButtonStyle -> None

In[20]:=

Plot[Cos[Sqrt[α]], {α, 0, 2 Pi}, AxesLabel -> {TraditionalForm @ α, TraditionalForm @ Cos[Sqrt[α]]}, TextStyle -> {FontFamily -> "Times", FontSize -> 14}, PlotLabel -> StyleForm["Ein schöner Plot\n", "Section", FontColor -> Hue[.1]]] ;

[Graphics:HTMLFiles/index_33.gif]

In[21]:=

Options[TickListPlot] = {HorizontalTickStart -> 0.15, NumberOfHorizontalTicks -> 4, Replace -> {}, TickStringFunction -> Identity} ;  TickListPlot[liin : {{_, _ ? NumberQ} ..}, (opts___) ? OptionQ] := Module[{hticks, lenli, tickstart, tickfun, nrofticks, rep, li = liin}, {nrofticks, tickstart, tickfun, rep} = {NumberOfHorizontalTicks, HorizontalTickStart, TickStringFunction, Replace} /. {opts} /. Options[TickListPlot] ;  li = li /. rep ;  lenli = Length[li] ; hticks = Table[{i, tickfun[If[! StringQ[li[[i, 1]]], ToString[li[[i, 1]]], li[[i, 1]]]]}, {i, Max[1, Round[tickstart * lenli]], lenli, Round[lenli/nrofticks]}] ;  ListPlot[li[[All, 2]], Ticks -> {hticks, Automatic}, FrameTicks -> {hticks, Automatic, None, None}, Sequence @@ ({opts} /. {(NumberOfHorizontalTicks | HorizontalTickStart | TickStringFunction -> _) :> Sequence[]})]] ; Null

In[24]:=

OptionSettings[ListPlot]

Out[24]//StyleForm=

AspectRatio -> 1/GoldenRatio
Axes -> Automatic
AxesLabel -> None
AxesOrigin -> Automatic
AxesStyle -> Automatic
Background -> Automatic
ColorOutput -> Automatic
DefaultColor -> Automatic
DefaultFont :> $DefaultFont
DisplayFunction :> $DisplayFunction
Epilog -> {}
FormatType :> $FormatType
Frame -> False
FrameLabel -> None
FrameStyle -> Automatic
FrameTicks -> Automatic
GridLines -> None
ImageSize -> Automatic
PlotJoined -> False
PlotLabel -> None
PlotRange -> Automatic
PlotRegion -> Automatic
PlotStyle -> Automatic
Prolog -> {}
RotateLabel -> True
TextStyle :> $TextStyle
Ticks -> Automatic

In[25]:=

TickListPlot[ {{ "1980", 32.5}, {"1985", 44.6}, {"1988", 49.6}, {1990, 49.6}}, PlotJoined -> True]

[Graphics:HTMLFiles/index_71.gif]

Out[25]=

-Graphics -

Ein weiterer neuer Operator ist \[InvisibleTimes]. Der folgende Ausdruck, 2\[InvisibleTimes]3 steht für das Produkt von 2 mal 3. Man sieht dies leicht durch Unformatieren der Zelle (mittels des "Show Expression" Menüs unter "Format").

In[26]:=

2  b 3

Out[26]=

6

In[27]:=

Grid[{{a, b}, {c, ddd}}, ColumnAlignments -> Right] // DisplayForm

Out[27]//DisplayForm=

a b
c ddd

Grid aktzeptiert dieselben Optionen wie GridBox:

In[28]:=

OptionSettings[GridBox]

Out[28]//StyleForm=

AllowScriptLevelChange -> True
AutoDelete -> True
ColumnAlignments -> {Center}
ColumnLines -> False
ColumnsEqual -> False
ColumnSpacings -> 0.800000011920929`
ColumnWidths -> Automatic
GridBaseline -> Axis
GridDefaultElement :> O
GridFrame -> False
GridFrameMargins -> {{0.4000000059604645`, 0.4000000059604645`}, {0.5`, 0.5`}}
MultilineFunction -> None
RowAlignments -> Baseline
RowLines -> False
RowMinHeight -> 1.`
RowsEqual -> False
RowSpacings -> 1.`

Hier ist eine Art J/Link-basierte OK-box, die einen oder zwei Zeilen Text in einer Dialog-Box anzeigt und wartet bis OK oder Cancel geclickt wird. Der Rückgabewert ist True oder False. Dieses kleine Beispiel kann zum Debuggen von FrontEnd Programmen benutzt werden, ganz ähnlich zu Dialog.

In[29]:=

Options[OKBox]=RGBColor->{{0.152941,0.796078,0.847059},{1,1,1}};
OKBox[a__,opts___?OptionQ]:=OKBox[StringJoin[ToString/@{a}],opts];
OKBox[text_String,opts___?OptionQ]:=OKBox[text,""];
OKBox[text_String,text2_String,opts___?OptionQ]:=
  CompoundExpression[Needs["JLink`"];
    ToExpression["JLink`InstallJava"][];
    ToExpression["JLink`JavaBlock"][
      Module[{frm,buttton,cancelbuttton,col,j,textField,windowListener,
          butttonListener,okbuttton,panel,s1,s2,s3,s4,textLabel,textLabel2,
          wasOKButton},{s1,s2,s3,s4}={200,200,700,200};
        j=ToExpression[StringJoin["JLink`",#1]]&;
        frm=j["JavaNew"]["com.wolfram.jlink.MathJFrame"];
        col=(N[RGBColor/.{opts}/.Options[OKBox]]);
        panel=j["JavaNew"]["javax.swing.JPanel"];
        panel@setLayout[Null];
        textLabel=j["JavaNew"]["javax.swing.JLabel",text];
        textLabel2=j["JavaNew"]["javax.swing.JLabel",text2];
        textLabel@setBounds[15,15,s3-50,50];
        textLabel2@setBounds[15,40,s3-50,50];
        okbuttton=j["JavaNew"]["javax.swing.JButton","OK"];
        okbuttton@setBounds[25,s2-90,60,40];
        cancelbuttton=j["JavaNew"]["javax.swing.JButton","Cancel"];
        cancelbuttton@setBounds[s3-120,s2-90,80,40];
        panel@add[okbuttton];
        panel@add[cancelbuttton];
        panel@add[textLabel];panel@add[textLabel2];
        okbuttton@
          addActionListener[
            j["JavaNew"]["com.wolfram.jlink.MathActionListener",
              "(EndModal[]; True)&"]];
        cancelbuttton@
          addActionListener[
            j["JavaNew"]["com.wolfram.jlink.MathActionListener",
              "(EndModal[]; False)&"]];
        frm@getContentPane[]@add[panel];
        frm@setSize[s3,s4];
        okbuttton@
          setBackground[j["JavaNew"]["java.awt.Color",Sequence@@col[[1]]]];
        cancelbuttton@
          setBackground[j["JavaNew"]["java.awt.Color",Sequence@@col[[2]]]];
        okbuttton@setSelected[True];
        j["JavaShow"][frm];
        wasOKButton=j["DoModal"][];frm@dispose[];
        If[TrueQ[wasOKButton],True,False]]]];

In[33]:=

TableForm[{{ a, bbbb}, {c, d}}]

Out[33]//TableForm=

a bbbb
c d

In[34]:=

TableForm[{{ a, bbbb}, {c, d}}] >> (tmp = OpenTemporary[][[1]])

In[35]:=

Import[tmp, "Text"]

Out[35]=

TableForm[{{a, bbbb}, {c, d}}]\n

In[36]:=

Clear[tmp]

In[37]:=

TextForm[TableForm[{{ a, bbbb}, {c, d}}, TableSpacing -> {0, 1}]] >> (tmp = OpenTemporary[][[1]])

In[38]:=

Import[tmp, "Text"]

Out[38]=

a bbbb\nc d\n

In[39]:=

% // InputForm

Out[39]//InputForm=

a bbbb\nc d\n

Die beiden buttons unten sind wie folgt zu gebrauchen: Man selektiere ein mit englischen Hochkommas geschriebene Wort (oder eine ganze Textpassage), inklusive der Hochkommas. Durch Klicken auf den Button werden nun die englischen Hochkommas in deutsche verwandelt. Die Abstände sind so optimiert dass es ausgedruckt gut aussieht. Natürlich ist dieser ”workaround“ nicht perfekt.

In[40]:=

Module[{r, nr}, r = NotebookRead[InputNotebook[]] ;  If[StringQ[r], If[StringMatchQ[r, "\"*\""], r = StringDrop[StringDrop[r, -1], 1]] ;  nr = TextData[{Cell[BoxData[FormBox[AdjustmentBox["”", BoxMargins -> {{0.0910714`, -0.0910714`}, {-1.19118`, 1.19118`}}, BoxBaselineShift -> 1.19118`], TraditionalForm]], AutoStyleOptions -> {"UnmatchedBracketStyle" -> None}], r <> "“"}] ;  NotebookWrite[InputNotebook[], nr]]] ;

Anführungsstriche

In[41]:=

Module[{r, nr}, r = NotebookRead[InputNotebook[]] ;  If[StringQ[r], If[StringMatchQ[r, "\"*\""], r = StringDrop[StringDrop[r, -1], 1]] ;  nr = TextData[{Cell[BoxData[FormBox[AdjustmentBox["”", BoxMargins -> {{0.0910714`, -0.0910714`}, {-1.19118`, 1.19118`}}, BoxBaselineShift -> 1.19118`], TraditionalForm]], AutoStyleOptions -> {"UnmatchedBracketStyle" -> None}], StyleBox[r <> "“", LineBreakWithin -> False]}] ; NotebookWrite[InputNotebook[], nr]]]

Anführungsstriche ohne Zeilenumbruch

FrontEnd

siehe Beispiel OKBox unter FrontEnd

ImportURL ist ähnlich zur GetURL Funktion aus der J/Link Dokumentation und lädt einen Text direkt vom Internet als String.

ImportRemoteNB öffnet Mathematica notebooks direkt.

In[42]:=

Needs["JLink`"];Off[General::spell1];

ImportURL::usage="ImportURL[URL] lädt die URL als string direkt in Mathematica, ohne temporäre Zwischenablagen auf der Festplatte. Die URL sollte entweder im Text Format oder im gzip Format sein.";

ImportRemoteNB::usage="ImportRemoteNB[URL] importiert die URL als Mathematica notebook.";

ImportURL[url_String] := JavaBlock[
     Module[{u, s = "", stream, numRead, buf},
     (* InstallJava[] lädt die Java Run Time *)
     InstallJava[];
     (* Hier wird die java.net.URL Klasse geladen *)
     u = JavaNew["java.net.URL", url];
     (* Der stream zur URL wird hergestellt mittels der java.net.URL Methode openStream *)
     stream = u@openStream[];
     If[StringMatchQ[url, "*.gz"],
     stream=JavaNew["java.util.zip.GZIPInputStream",stream]];
     (* Fehlerbedingung *)
     If[stream === $Failed, Return[$Failed]];
     (* Die Verbindung steht und jetzt wird per buffer jeder Character eingelesen *)
     buf = JavaNew["[B", 5000];
     While[(numRead = stream[read[buf]]) > 0,
     s = s <> FromCharacterCode[(If[#1 < 0, #1 + 256, #1] & ) /@ Take[Val[buf], numRead]]];
     stream[close[]]; s]];
            
ImportRemoteNB[nb_String] := NotebookPut[Import[StringToStream[ImportURL[nb]], "NB"]]

In[48]:=

ImportURL["http://gutenberg.spiegel.de/goethe/gedichte/Druckversion_regel.htm"]

Out[48]=

<HTML>\r\n<HEAD>\r\n<TITLE>Goldene Regel</TITLE>\r\n<META NAME=\"TYPE\"       CONTENT=\"POEM\">\r\n<META NAME=\"BOOKTITLE\"  CONTENT=\"Gesammelte Werke in sieben B&auml;nden\">\r\n<META NAME=\"AUTHOR\"     CONTENT=\"Johann Wolfgang Goethe\">\r\n<META NAME=\"EDITOR\"     CONTENT=\"Bernt von Heiseler\">\r\n<META NAME=\"YEAR\"       CONTENT=\"o.J.\">\r\n<META NAME=\"PUBLISHER\"  CONTENT=\"Bertelsmann Lesering\">\r\n<META NAME=\"ADDRESS\"    CONTENT=\"G&uuml;tersloh\">\r\n<META NAME=\"TITLE\"      CONTENT=\"Goldene Regel\">\r\n<META NAME=\"PAGES\"      CONTENT=\"297\">\r\n<META NAME=\"CREATED\"    CONTENT=\"19990207\">\r\n<META NAME=\"SENDER\"     CONTENT=\"gerd.bouillon@t-online.de\">\r\n<link rel=\"stylesheet\" HREF=\"../../css/poem.css\" TYPE=\"text/css\">\r\n</HEAD>\r\n<BODY>\r\n\r\n<H3 align=\"center\">Goldene Regel</H3>\r\n<P>\r\n<TABLE align=\"center\"><TR><TD>&nbsp; &nbsp; &nbsp; &nbsp;<TD>\r\nMit einem Herren steht es gut,<BR>\r\nDer, was er befohlen, selber tut.\r\n</TABLE>\r\n</BODY>\r\n</HTML>\r\n

In[49]:=

ImportRemoteNB["http://www.mertig.com/mathdepot/ButtonTools.nb"]

Out[49]=

NotebookObject[<< Untitled-1 >>]

In[50]:=

Needs["JLink`"] ; Off[General :: spell] ; Off[General :: spell1] ;

In[51]:=

GZIPURLAsString[url_String] := JavaBlock[Module[{u, stream, numRead, outFile, buf, s}, InstallJava[] ;  u = JavaNew["java.net.URL", url] ;  stream = u @ openStream[] ;  stream = JavaNew["java.util.zip.GZIPInputStream", stream] ;  If[stream === $Failed, Return[$Failed]] ;  buf = JavaNew["[B", 50000] ;  s = "" ;  While[(numRead = stream @ read[buf]) > 0, s = (s <> FromCharacterCode[(If[# < 0, # + 256, #] &) /@ Take[Val[buf], numRead]])] ;  stream @ close[] ;  s]]

In[52]:=

JavaInput::usage="JavaInput[titeltext, defaultinput]";

JavaInput[title_String, pwd_String] :=
Module[{jC},Needs["JLink`"];
jC[s_String] := ToExpression[StringJoin["JLink`", s]];
jC["InstallJava"][];
  jC["JavaBlock"][
    Module[{frm, buton, textField, butonListener, okbuton, cancelbuton, w, h,
        t}, frm = jC["JavaNew"]["com.wolfram.jlink.MathJFrame"];
      w = 350; h = w/GoldenRatio // N // Round;
      t = 150; cornerleft = 50; {okx, oky, cancelx} = {60, 40, 80};
      panel = jC["JavaNew"]["javax.swing.JPanel"];
      panel@setLayout[Null];
      titleLabel = jC["JavaNew"]["javax.swing.JLabel", title];
      titleLabel@setBounds[85, 20, 2t, 25];
      okbuton = jC["JavaNew"]["javax.swing.JButton", "OK"];
      okbuton@setBounds[cornerleft, h - (cornerleft + okx), okx, oky];
      cancelbuton = jC["JavaNew"]["javax.swing.JButton", "Cancel"];
      cancelbuton@
        setBounds[w - cornerleft - cancelx, h - (cornerleft + okx), cancelx,
          oky];
      textField = jC["JavaNew"]["javax.swing.JTextField", pwd, 20];
      textField@setBounds[Round[w/2 - t/2], 50, Round[0.8 t], 25];
      panel@add[textField];
      panel@add[okbuton];
      panel@add[cancelbuton];
      panel@add[titleLabel];
      okbuton@
        addActionListener[
          jC["JavaNew"]["com.wolfram.jlink.MathActionListener",
            "(EndModal[]; True)&"]];
      cancelbuton@
        addActionListener[
          jC["JavaNew"]["com.wolfram.jlink.MathActionListener",
            "(EndModal[]; False)&"]];
      frm@getContentPane[]@add[panel];
      frm@setSize[w, h];
     jC["JavaShow"][frm];
      frm@setModal[];
      wasOKButton = jC["DoModal"][]; frm@dispose[];
      If[TrueQ[wasOKButton], passwd = textField@getText[], passwd = $Failed]
      ]]];

In[54]:=

JavaInput["Titel", "Voreinstellung"] // InputForm

Out[54]//InputForm=

Voreinstellung

Leider ist das neue Combinatorica Paket nicht gut dokumentiert und nicht kompatibel mit frühreren Versionen.

Hier ein kleiner Fix für ShowGraph der für das Buchs "Diskrete Mathematik - Basiswissen für Informatiker"

In[55]:=

Needs["DiscreteMath`Combinatorica`"] ;

In[56]:=

If[$VersionNumber >= 4.2, Unprotect[ShowGraph] ;  Graph /: ShowGraph[Graph[(m_) ? MatrixQ, r__], Directed, (opts___) ? OptionQ] := ShowGraph[Graph[First[FromAdjacencyMatrix[m, Type -> Directed]], List /@ r], EdgeDirection -> On, opts] ;  Graph /: ShowGraph[Graph[(m_) ? MatrixQ, r__], (opts___) ? OptionQ] := ShowGraph[Graph[First[FromAdjacencyMatrix[m]], List /@ r], EdgeDirection -> Off, opts]] <br />


Converted by Mathematica  (March 11, 2003)